home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 2.iso / dist / fw_glimpse.idb / usr / freeware / src / glimpse-3.0 / libtemplate / util / system.c.z / system.c
C/C++ Source or Header  |  1997-09-09  |  6KB  |  226 lines

  1. static char rcsid[] = "$Id: system.c,v 1.22 1995/02/04 01:37:57 hardy Exp $";
  2. /*
  3.  *  system.c - system(3) routines for Essence system.
  4.  *
  5.  *  Darren Hardy, hardy@cs.colorado.edu, February 1994
  6.  *
  7.  *  ----------------------------------------------------------------------
  8.  *  Copyright (c) 1994, 1995.  All rights reserved.
  9.  *  
  10.  *          Mic Bowman of Transarc Corporation.
  11.  *          Peter Danzig of the University of Southern California.
  12.  *          Darren R. Hardy of the University of Colorado at Boulder.
  13.  *          Udi Manber of the University of Arizona.
  14.  *          Michael F. Schwartz of the University of Colorado at Boulder. 
  15.  *  
  16.  *  This copyright notice applies to all code in Harvest other than
  17.  *  subsystems developed elsewhere, which contain other copyright notices
  18.  *  in their source text.
  19.  *  
  20.  *  The Harvest software was developed by the Internet Research Task
  21.  *  Force Research Group on Resource Discovery (IRTF-RD).  The Harvest
  22.  *  software may be used for academic, research, government, and internal
  23.  *  business purposes without charge.  If you wish to sell or distribute
  24.  *  the Harvest software to commercial clients or partners, you must
  25.  *  license the software.  See
  26.  *  http://harvest.cs.colorado.edu/harvest/copyright,licensing.html#licensing.
  27.  *  
  28.  *  The Harvest software is provided ``as is'', without express or
  29.  *  implied warranty, and with no support nor obligation to assist in its
  30.  *  use, correction, modification or enhancement.  We assume no liability
  31.  *  with respect to the infringement of copyrights, trade secrets, or any
  32.  *  patents, and are not responsible for consequential damages.  Proper
  33.  *  use of the Harvest software is entirely the responsibility of the user.
  34.  *  
  35.  *  For those who are using Harvest for non-commercial purposes, you may
  36.  *  make derivative works, subject to the following constraints:
  37.  *  
  38.  *  - You must include the above copyright notice and these accompanying 
  39.  *    paragraphs in all forms of derivative works, and any documentation 
  40.  *    and other materials related to such distribution and use acknowledge 
  41.  *    that the software was developed at the above institutions.
  42.  *  
  43.  *  - You must notify IRTF-RD regarding your distribution of the 
  44.  *    derivative work.
  45.  *  
  46.  *  - You must clearly notify users that your are distributing a modified 
  47.  *    version and not the original Harvest software.
  48.  *  
  49.  *  - Any derivative product is also subject to the restrictions of the 
  50.  *    copyright, including distribution and use limitations.
  51.  */
  52. #include <stdlib.h>
  53. #include <unistd.h>
  54. #include <sys/wait.h>
  55. #include <signal.h>
  56. #include <fcntl.h>
  57. #include "util.h"
  58. #ifdef HAVE_SETRLIMIT
  59. #include <sys/time.h>
  60. #include <sys/resource.h>
  61. #endif
  62.  
  63. static void redirect_stdout();
  64.  
  65. /*
  66.  *  do_system() - calls system(3).
  67.  */
  68. int do_system(cmd)
  69. char *cmd;
  70. {
  71. #ifdef DEBUG
  72.     log("RUNNING as shell: %s\n", cmd);
  73. #endif
  74.     return (system(cmd));
  75. }
  76.  
  77. /*
  78.  *  run_cmd() - simplified system(3).  Parses the command, will redirect
  79.  *  stdout and then fork/exec() to save a sh process.
  80.  */
  81. int run_cmd(cmd)
  82. char *cmd;
  83. {
  84.     int pid, status = 0;
  85.  
  86. #ifdef DEBUG
  87.     log("RUNNING: %s\n", cmd);
  88. #endif
  89.  
  90. /*
  91.    ** PURFIY:
  92.    ** use fork() here instead of vfork().  With vfork parent and child
  93.    ** share memory space.  In the child we strdup a bunch of argv's
  94.    ** which would otherwise never get free'd causing a memory leak in
  95.    ** the parent.
  96.  */
  97.     if ((pid = fork()) < 0) {
  98.         log_errno("run_cmd: fork");
  99.         return (1);
  100.     }
  101.     if (pid == 0) {        /* child */
  102.         char *argv[64], buf[BUFSIZ];
  103.         int i;
  104.  
  105.         memset(argv, '\0', sizeof(char *) * 64);
  106.         parse_argv(argv, cmd);
  107.         for (i = 0; argv[i] != NULL; i++) {
  108.             if (argv[i][0] == '>' && argv[i + 1] != NULL) {
  109.                 argv[i] = NULL;
  110.                 redirect_stdout(argv[++i]);
  111.                 break;
  112.             }
  113.         }
  114.         execvp(argv[0], argv);
  115.         sprintf(buf, "execvp: %s", argv[0]);
  116.         log_errno(buf);
  117.         _exit(1);
  118.     }
  119.     /* parent */
  120.     (void) waitpid(pid, &status, (int) NULL);
  121.     return (WEXITSTATUS(status));
  122. }
  123.  
  124. static void redirect_stdout(filename)
  125. char *filename;
  126. {
  127.     int fd;
  128.  
  129.     if (filename == NULL)
  130.         return;
  131.     if ((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
  132.         log_errno(filename);
  133.         return;
  134.     }
  135.     close(1);
  136.     dup2(fd, 1);        /* make stdout */
  137. }
  138.  
  139. static int dsl_pid = -1;
  140. static void alarm_handler()
  141. {
  142. #ifdef DEBUG
  143.     log("do_system_lifetime: Caught signal.  Killing %d.\n", dsl_pid);
  144. #endif
  145.     (void) kill(dsl_pid, SIGTERM);
  146.     sleep(1);
  147.     (void) kill(dsl_pid, SIGKILL);
  148. }
  149.  
  150. /*
  151.  *  do_system_lifetime() - calls system(3).  Only lives for lifetime seconds.
  152.  */
  153. void do_system_lifetime(cmd, lifetime)
  154. char *cmd;
  155. int lifetime;
  156. {
  157. #ifdef DEBUG
  158.     log("RUNNING: %s\n", cmd);
  159.     log("do_system_lifetime: Lifetime is %d seconds.\n", lifetime);
  160. #endif
  161.     signal(SIGALRM, alarm_handler);
  162.     alarm(lifetime);
  163. /*
  164.    ** PURFIY:
  165.    ** use fork() here instead of vfork().  With vfork parent and child
  166.    ** share memory space.  In the child we strdup a bunch of argv's
  167.    ** which would otherwise never get free'd causing a memory leak in
  168.    ** the parent.
  169.  */
  170.     if ((dsl_pid = fork()) < 0) {
  171.         log_errno("fork");
  172.         return;
  173.     }
  174.     if (dsl_pid) {        /* parent */
  175.         (void) waitpid(dsl_pid, (int *) NULL, (int) NULL);
  176.         alarm(0);
  177.         return;
  178.     } else {        /* child */
  179.         char *argv[64];    
  180.         char buf[BUFSIZ], i;
  181.  
  182.         alarm(0);
  183.         memset(argv, '\0', sizeof(char *) * 64);
  184.         parse_argv(argv, cmd);
  185.         for (i = 0; argv[i] != NULL; i++) {
  186.             if (argv[i][0] == '>' && argv[i + 1] != NULL) {
  187.                 argv[i] = NULL;
  188.                 redirect_stdout(argv[++i]);
  189.                 break;
  190.             }
  191.         }
  192. #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CPU)
  193.         {
  194.             struct rlimit rlp;
  195.             rlp.rlim_cur = rlp.rlim_max = lifetime;
  196.             (void) setrlimit(RLIMIT_CPU, &rlp);
  197.         }
  198. #endif
  199.         execvp(argv[0], argv);
  200.         sprintf(buf, "execvp: %s", argv[0]);
  201.         log_errno(buf);
  202.         _exit(1);
  203.     }
  204. }
  205.  
  206. /*
  207.  *  close_all_fds() - closes all of the file descriptors starting with start.
  208.  */
  209. void close_all_fds(start)
  210. int start;
  211. {
  212.     int i;
  213.  
  214. #if   defined(HAVE_GETDTABLESIZE)
  215.     for (i = start; i < getdtablesize(); i++) {
  216. #elif defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
  217.     for (i = start; i < sysconf(_SC_OPEN_MAX); i++) {
  218. #elif defined(OPEN_MAX)
  219.     for (i = start; i < OPEN_MAX; i++) {
  220. #else
  221.     for (i = start; i < 64; i++) {
  222. #endif
  223.         (void) close(i);
  224.     }
  225. }
  226.